package com.tian.controller.api;

import com.tian.es.entity.GeoLocationPoiVo;
import com.tian.es.entity.ChargeStationLocation;
import com.tian.es.entity.NearByPoiParam;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * {@code @description:} TODO
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-07-23 15:53
 * {@code @version:} 1.0
 */
@RestController
@RequestMapping("/api/es")
public class EsController {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    public void createIndex() {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(ChargeStationLocation.class);
        indexOperations.create();
        Document mapping = indexOperations.createMapping();
        indexOperations.putMapping(mapping);
    }

    /**
     * 删除索引
     */
    @GetMapping("/delete")
    public void delete() {
        elasticsearchRestTemplate.delete("1", ChargeStationLocation.class);
    }

    @GetMapping("/save")
    public void save() throws Exception {
//        createIndex();
        List<ChargeStationLocation> chargeStationLocationList = new ArrayList<>();
            ChargeStationLocation chargeStationLocation = new ChargeStationLocation();
            chargeStationLocation.setId(4L);
            chargeStationLocation.setName("站点4");
            chargeStationLocation.setAddress("详细地址4");
            GeoPoint geoPoint = new GeoPoint(21.3899853, 110.2390409);
            chargeStationLocation.setGeoPoint(geoPoint);

            chargeStationLocationList.add(chargeStationLocation);

//        LocationPoiVo locationPoiVo1 = new LocationPoiVo();
//        locationPoiVo1.setId(2L);
//        locationPoiVo1.setName("站点2");
//        locationPoiVo1.setAddress("详细地址2");
//        locationPoiVo1.setPhone("182765403721");
//        locationPoiVo1.setCatalog("2");
//        GeoPoint geoPoint1 = new GeoPoint(21.2356713,110.3891208 );
//        locationPoiVo1.setGeoPoint(geoPoint1);

//        locationPoiVoList.add(locationPoiVo1);

        elasticsearchRestTemplate.save(chargeStationLocationList);
    }
    @GetMapping("/getNearByPoi")
    public List<GeoLocationPoiVo> getNearByPoi() {
        NearByPoiParam nearByPoiParam=new NearByPoiParam();
        nearByPoiParam.setLat(21.2356713);
        nearByPoiParam.setLon(110.3891208);
        nearByPoiParam.setDistance(200);
        List<GeoLocationPoiVo> geoLocationPoiVoList = new ArrayList<>();

        Pageable pageable = PageRequest.of(0, nearByPoiParam.getSize());

        // 搜索字段为 location
        GeoDistanceQueryBuilder geoBuilder = new GeoDistanceQueryBuilder("geoPoint");
        //指定从哪个位置搜索
        geoBuilder.point(nearByPoiParam.getLat(), nearByPoiParam.getLon());
        //指定搜索多少km
        geoBuilder.distance(nearByPoiParam.getDistance(), DistanceUnit.KILOMETERS);

        // 距离排序
        GeoDistanceSortBuilder sortBuilder = new GeoDistanceSortBuilder("geoPoint", nearByPoiParam.getLat(), nearByPoiParam.getLon());
        //升序
        sortBuilder.order(SortOrder.ASC);

        SearchHits<ChargeStationLocation> searchHits = elasticsearchRestTemplate
                .search(new NativeSearchQueryBuilder()
                        .withPageable(pageable)
                        .withFilter(geoBuilder)
                        .withSort(sortBuilder)
                        .build(), ChargeStationLocation.class);
        searchHits.forEach(searchHit -> {
            double calculate = GeoDistance.PLANE.calculate(searchHit.getContent().getGeoPoint().getLat(), searchHit.getContent().getGeoPoint().getLon(), nearByPoiParam.getLat(), nearByPoiParam.getLon(), DistanceUnit.METERS);
            GeoLocationPoiVo geoLocationPoiVo = new GeoLocationPoiVo();
            BeanUtils.copyProperties(searchHit.getContent(), geoLocationPoiVo);
            geoLocationPoiVo.setSpecificDistance(calculate + "米");
            geoLocationPoiVoList.add(geoLocationPoiVo);
        });
        return geoLocationPoiVoList;
    }

}
